<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<![endif]-->
<title>VIM 中文帮助: 标签及特殊查找</title>
<link rel="stylesheet" href="vim-stylesheet.css" type="text/css" />
<link rel="canonical" href="https://yianwillis.github.io/vimcdoc/doc/tagsrch.html" />
<script type="text/javascript" src="vimcdoc.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<nav id=banner>
<form action=tags.html target="tag_iframe">
  <input type="text" name="tag" id="tag" placeholder="标签搜索">
</form>
<iframe name="tag_iframe" src=""></iframe>
<a href="help.html">帮助总览</a> &middot;
<hr/>
<a href="quickref.html">快速参考</a> &middot;
<a href="index.html">命令索引</a> &middot;
<a href="eval.html#functions">函数列表</a> &middot;
<a href="quickref.html#option-list">选项列表</a> &middot;
<hr/>
<a href="usr_toc.html">用户手册</a> &middot;
<a href="help.html#reference_toc">参考手册</a> &middot;
</nav>

<header>
<h2>tagsrch</h2>
</header>
<article id=outer>
<section class=inner>
<b class="vimtag"> <a name="tagsrch.txt">tagsrch.txt</a> </b>   适用于 Vim 9.0 版本。   最近更新: 2022年9月


                  <code class="vim">VIM 参考手册    by Bram Moolenaar</code>
                                <code class="vim">译者</code>: Willis


标签和特殊搜索                                          <b class="vimtag"> <a name="tags-and-searches">tags-and-searches</a> </b>

用户手册  <a href="usr_29.html#29.1">29.1</a>  有这部分内容的介绍。

1. 跳转到标签                    <a href="tagsrch.html#tag-commands">tag-commands</a> 
2. 标签栈                        <a href="tagsrch.html#tag-stack">tag-stack</a> 
3. 标签匹配表                    <a href="tagsrch.html#tag-matchlist">tag-matchlist</a> 
4. 标签细节                      <a href="tagsrch.html#tag-details">tag-details</a> 
5. 标签文件格式                  <a href="tagsrch.html#tags-file-format">tags-file-format</a> 
6. 头文件搜索                    <a href="tagsrch.html#include-search">include-search</a> 
7. 使用 <a href="options.html#'tagfunc'">'tagfunc'</a>                <a href="tagsrch.html#tag-function">tag-function</a> 

</section><hr class="doubleline" /><section class=inner>
<h4>1. 跳转到标签                                           <b class="vimtag"> <a name="tag-commands">tag-commands</a> </b></h4>
                                                        <b class="vimtag"> <a name="tag">tag</a> </b> <b class="vimtag"> <a name="tags">tags</a> </b>
标签是出现在 "tags" 文件的一个标识符。它是一种能够跳转的标记。例如，在 C 程序
里，每个函数名都可以是一个标签。在使用标签文件之前，"tags" 文件由 ctags 这样的
程序生成。

使用 ":tag" 命令移动光标到标签上。使用 <code class="keystroke">CTRL-]</code> 命令，光标所在的关键字就可用作标
签。如果光标不在关键字上，则使用最右侧的一个关键字。

":tag" 命令对 C 程序十分有效。如果你看到一个函数的调用而想知道该函数的作用，把
光标移动到函数名上，并按 <code class="keystroke">CTRL-]</code>。它会把你带到该函数的定义上。简单的，按 <code class="keystroke">CTRL-T</code>
就可以回去。同时，也请阅读下面关于标签栈的描述。

                                                <b class="vimtag"> <a name=":ta">:ta</a> </b> <b class="vimtag"> <a name=":tag">:tag</a> </b> <b class="vimtag"> <a name="E426">E426</a> </b> <b class="vimtag"> <a name="E429">E429</a> </b>
:<code class="special">[count]</code>ta[g][!] <code class="special">{name}</code>
                        根据 tags 文件的信息，跳转到 <code class="special">{name}</code> 的定义上。
                        把 <code class="special">{name}</code> 放在堆栈上。[!] 见  <a href="tagsrch.html#tag-!">tag-!</a> 。
                        <code class="special">{name}</code> 可以是正则表达式。见  <a href="tagsrch.html#tag-regexp">tag-regexp</a> 。
                        如果有 <code class="special">{name}</code> 的多个匹配，则跳转到它们中的第 <code class="special">[count]</code>
                        个。如果 <code class="special">[count]</code> 被省略，则跳转到第一个。要跳转到其它
                        匹配的标签，参见  <a href="tagsrch.html#tag-matchlist">tag-matchlist</a> 。

g<code class="special">&lt;LeftMouse&gt;</code>                                            <b class="vimtag"> <a name="g%3CLeftMouse%3E">g&lt;LeftMouse&gt;</a> </b>
<code class="special">&lt;C-LeftMouse&gt;</code>                                   <b class="vimtag"> <a name="%3CC-LeftMouse%3E">&lt;C-LeftMouse&gt;</a> </b> <b class="vimtag"> <a name="CTRL-]">CTRL-]</a> </b>
<code class="keystroke">CTRL-]</code>                  跳转到光标所在的关键字的定义。和 ":tag <code class="special">{name}</code>" 相同，
                        只不过 <code class="special">{name}</code> 是光标之下或者之后的关键字。
                        如果有 <code class="special">{name}</code> 的多个匹配，则跳转到它们中的第 <code class="special">[count]</code>
                        个。如果没有 <code class="special">[count]</code>，跳转到第一个。 要跳转到其它匹配
                        的标签，参见  <a href="tagsrch.html#tag-matchlist">tag-matchlist</a> 。

                                                        <b class="vimtag"> <a name="v_CTRL-]">v_CTRL-]</a> </b>
<code class="special">{Visual}</code><code class="keystroke">CTRL-]</code>          和 ":tag <code class="special">{name}</code>" 相同，其中 <code class="special">{name}</code> 是高亮的文本。

                                                        <b class="vimtag"> <a name="telnet-CTRL-]">telnet-CTRL-]</a> </b>
<code class="keystroke">CTRL-]</code> 是缺省的 telnet 转义键。在你按 <code class="keystroke">CTRL-]</code> 进行标签跳转的时候，你会得到
telnet 的提示符。许多版本的 telnet 允许你改变或者屏蔽缺省的转义键。见 telnet
的手册页。你可以用 'telnet -E <code class="special">{Hostname}</code>' 来屏蔽转义键，或者用 'telnet -e
<code class="special">{EscapeCharacter}</code> <code class="special">{Hostname}</code>' 来指定别的转义键。如果可能，用 "ssh" 来代替
"telnet" 也可解决这个问题。

                                                        <b class="vimtag"> <a name="tag-priority">tag-priority</a> </b>
如果有标签的多个匹配，使用以下的优先级:
1. "FSC"  当前文件的完整的匹配静态标签。
2. "F C"  当前文件的完整匹配全局标签。
3. "F  "  其他文件的完整匹配全局标签。
4. "FS "  其他文件的完整匹配静态标签。
5. " SC"  当前文件的忽略大小写的匹配静态标签。
6. "  C"  当前文件的忽略大小写匹配全局标签。
7. "   "  其他文件的忽略大小写匹配全局标签。
8. " S "  其他文件的忽略大小写匹配静态标签。

<code class="note">注意</code> 当前文件改变时，优先顺序多数情况下不会改变，以免使 ":tnext" 的使用引起混
淆。在使用 ":tag <code class="special">{name}</code>" 时，优先顺序才会改变。

以下情况下，":tag" 命令不会查找忽略大小写的匹配:
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "followic" 且 <a href="options.html#'ignorecase'">'ignorecase'</a> 选项关闭
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "followscs" 且 <a href="options.html#'ignorecase'">'ignorecase'</a> 选项关闭且 <a href="options.html#'smartcase'">'smartcase'</a> 选项关闭或模
  式包含大写字符。(<code class="vim">译者注</code>: 原文如此，似不确)
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "match"
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "smart" 且模式包含大写字符。

以下情况下，查找忽略大小写的匹配:
- 使用模式 (以 "/" 开始)
- ":tselect"
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "followic" 且 <a href="options.html#'ignorecase'">'ignorecase'</a> 打开
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "followscs" 且 <a href="options.html#'ignorecase'">'ignorecase'</a> 打开或 <a href="options.html#'smartcase'">'smartcase'</a> 选项打开且模式不
  包含大写字符 (<code class="vim">译者注</code>: 原文如此，似不确)
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "ignore"
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "smart" 且模式不包含大写字符

<code class="note">注意</code> 使用忽略大小写查找就无法应用 tags 文件的二分法查找，从而减慢了查找速度。
这可以用大小写合并排序的标签文件来解决。具体解释见 <a href="options.html#'tagbsearch'">'tagbsearch'</a> 选项。

</section><hr class="doubleline" /><section class=inner>
<h4>2. 标签栈                               <b class="vimtag"> <a name="tag-stack">tag-stack</a> </b> <b class="vimtag"> <a name="tagstack">tagstack</a> </b> <b class="vimtag"> <a name="E425">E425</a> </b></h4>
标签栈记住你跳转过的标签，还有从哪里跳转到这些标签。只有在设置 <a href="options.html#'tagstack'">'tagstack'</a> 选项
的时候，标签才被压到堆栈里。

g<code class="special">&lt;RightMouse&gt;</code>                                           <b class="vimtag"> <a name="g%3CRightMouse%3E">g&lt;RightMouse&gt;</a> </b>
<code class="special">&lt;C-RightMouse&gt;</code>                                  <b class="vimtag"> <a name="%3CC-RightMouse%3E">&lt;C-RightMouse&gt;</a> </b> <b class="vimtag"> <a name="CTRL-T">CTRL-T</a> </b>
<code class="keystroke">CTRL-T</code>                  跳到标签栈上第 <code class="special">[count]</code> 个较早的项目 (缺省为 1)。

                                                <b class="vimtag"> <a name=":po">:po</a> </b> <b class="vimtag"> <a name=":pop">:pop</a> </b> <b class="vimtag"> <a name="E555">E555</a> </b> <b class="vimtag"> <a name="E556">E556</a> </b>
:<code class="special">[count]</code>po[p][!]        跳到标签栈上第 <code class="special">[count]</code> 个较早的项目 (缺省为 1)。
                        [!] 见  <a href="tagsrch.html#tag-!">tag-!</a> 。

:<code class="special">[count]</code>ta[g][!]        跳到标签栈上第 <code class="special">[count]</code> 个较新的项目 (缺省为 1)。
                        [!] 见  <a href="tagsrch.html#tag-!">tag-!</a> 。

                                                        <b class="vimtag"> <a name=":tags">:tags</a> </b>
:tags                   显示标签栈的内容。激活的项目以 '&gt;' 标明。

":tags" 的输出结果类似于:

   # TO tag      FROM line in file/text
   1  1 main             1  harddisk2:text/vim/test
 &gt; 2  2 FuncA           58  i = FuncA(10);
   3  1 FuncC          357  harddisk2:text/vim/src/amiga.c

该列表显示你跳转到的标签和跳转前光标的位置。较早的项目在顶部，较新的在底部。

'&gt;' 指向活动的项目。这是下一个 ":tag" 命令将使用的标签。<code class="keystroke">CTRL-T</code> 和 ":pop" 使用
活动项目之上的那项的位置。

"TO" 之下的那列显示匹配表的当前匹配的数目。<code class="note">注意</code> 这不会因为使用 ":pop" 或者
":tag" 而改变。

记住文件名和行号可以使你回到 tag 命令之前的位置。即使你删除或者插入行，行号也
会保持正确，除非你用别的程序 (比如，另外一个 Vim 的实例) 做这些事。

对于当前文件，"file/text" 列显示该位置的文本。缩进被删除，长行也被截短，以便能
放进窗口里显示。

有若干命令可以让你跳到之前用过的标签。一些例子包括:

        ":pop" 或 <code class="keystroke">CTRL-T</code>        到上一个标签之前的位置
        <code class="special">{count}</code><code class="keystroke">CTRL-T</code>           到第 <code class="special">{count}</code> 个较早的标签之前的位置
        ":tag"                  到更新的标签
        ":0tag"                 到前一个使用过的标签

最明显的应用就是浏览程序的调用图。考虑下面的调用图:

        main  ---&gt;  FuncA  ---&gt;  FuncC
              ---&gt;  FuncB

(解释: main 调用 FuncA 和 FuncB; FuncA 调用 FuncC)。
从 main 到 FuncA，你可以在调用 FuncA 的行上用 <code class="keystroke">CTRL-]</code>。然后再用 <code class="keystroke">CTRL-]</code> 跳到
FuncC。如果你现在想跳回到 main，你只需要按 <code class="keystroke">CTRL-T</code> 两次。然后你可以用 <code class="keystroke">CTRL-]</code> 到
FuncB。

如果你使用 ":ta <code class="special">{name}</code>" 或者 <code class="keystroke">CTRL-]</code> 命令，该标签被加在栈的当前位置。如果栈已满
(最多可以容纳 20 项)，最早的项目被删除，较早的项目则依次前移 (索引号分别减
1)。如果最近使用的项目不在底部，它其后的项目都被删除。这意味着调用图上的旧的分
支丢失了。在上面解释的命令执行以后，标签栈看起来像这样:

   # TO tag     FROM line in file/text
   1  1 main            1  harddisk2:text/vim/test
   2  1 FuncB          59  harddisk2:text/vim/src/main.c

 <a href="builtin.html#gettagstack()">gettagstack()</a>  函数返回指定窗口的标签栈。 <a href="builtin.html#settagstack()">settagstack()</a>  函数修改窗口的标签
栈。

                                                        <b class="vimtag"> <a name="tagstack-examples">tagstack-examples</a> </b>
像  <a href="tagsrch.html#:tag">:tag</a>  那样写入标签栈，但用用户自定义的 jumper#jump_to_tag 函数: 
<code class="example">        " 跳转前，先保存当前位置。</code>
<code class="example">        let tag = expand('&lt;cword&gt;')</code>
<code class="example">        let pos = [bufnr()] + getcurpos()[1:]</code>
<code class="example">        let item = {'bufnr': pos[0], 'from': pos, 'tagname': tag}</code>
<code class="example">        if jumper#jump_to_tag(tag)</code>
<code class="example">                " 跳转成功，把之前的位置写入标签栈。</code>
<code class="example">                let winid = win_getid()</code>
<code class="example">                let stack = gettagstack(winid)</code>
<code class="example">                let stack['items'] = [item]</code>
<code class="example">                call settagstack(winid, stack, 't')</code>
<code class="example">        endif</code>

设置标签栈的当前索引为 4: 
<code class="example">        call settagstack(1005, {'curidx' : 4})</code>

给标签栈压入新项目: 
<code class="example">        let pos = [bufnr('myfile.txt'), 10, 1, 0]</code>
<code class="example">        let newtag = [{'tagname' : 'mytag', 'from' : pos}]</code>
<code class="example">        call settagstack(2, {'items' : newtag}, 'a')</code>

                                                        <b class="vimtag"> <a name="E73">E73</a> </b>
如果你试图使用标签栈，而其中没有任何内容，你会得到一个错误信息。

</section><hr class="doubleline" /><section class=inner>
<h4>3. 标签匹配表                           <b class="vimtag"> <a name="tag-matchlist">tag-matchlist</a> </b> <b class="vimtag"> <a name="E427">E427</a> </b> <b class="vimtag"> <a name="E428">E428</a> </b></h4>
如果有多个匹配的标签，这些命令可以用来在它们之间跳转。<code class="note">注意</code> 这些命令不影响标签
栈，它保留原来的项目。

                                                        <b class="vimtag"> <a name=":ts">:ts</a> </b> <b class="vimtag"> <a name=":tselect">:tselect</a> </b>
:ts[elect][!] <code class="special">[name]</code>    根据 tags 文件的信息，列出匹配 <code class="special">[name]</code> 的标签。
                        如果 <code class="special">[name]</code> 没有给出，使用标签栈上最后的标签名。
                        关于 [!] 见  <a href="tagsrch.html#tag-!">tag-!</a> 。
                        第一列的 '&gt;' 指示列表的当前位置 (如果有的话)。
                        <code class="special">[name]</code> 可以是正则表达式，见  <a href="tagsrch.html#tag-regexp">tag-regexp</a> 。
                        列表使用的优先级顺序见  <a href="tagsrch.html#tag-priority">tag-priority</a> 。
                        示例输出:


<code class="example">          # pri kind tag                file</code>
<code class="example">          1 F   f    mch_delay          os_amiga.c</code>
<code class="example">                        mch_delay(msec, ignoreinput)</code>
<code class="example">        &gt; 2 F   f    mch_delay          os_msdos.c</code>
<code class="example">                        mch_delay(msec, ignoreinput)</code>
<code class="example">          3 F   f    mch_delay          os_unix.c</code>
<code class="example">                        mch_delay(msec, ignoreinput)</code>
<code class="example">        Type number and &lt;Enter&gt; (empty cancels):</code>

                        "pri" 列见  <a href="tagsrch.html#tag-priority">tag-priority</a> 。<code class="note">注意</code> 这决定于当前文件，因而
                        ":tselect xxx" 可能会输出不同的结果。
                        如果 tags 文件给出标签的类型。"kind" 列输出此信息。
                        "info" 列给出 tags 文件找到的信息。这决定于产生 tags
                        文件的程序。
                        如果列表很长，你可能会看到  <a href="message.html#more-prompt">more-prompt</a> 。如果你已经看
                        到要用的标签，按 'q' 并输入那个数字。

                                                        <b class="vimtag"> <a name=":sts">:sts</a> </b> <b class="vimtag"> <a name=":stselect">:stselect</a> </b>
:sts[elect][!] <code class="special">[name]</code>   ":tselect[!] <code class="special">[name]</code>" 并分割窗口以显示选择的标签。

                                                        <b class="vimtag"> <a name="g]">g]</a> </b>
g]                      类似于 <code class="keystroke">CTRL-]</code>，但使用 ":tselect" 而不是 ":tag"。

                                                        <b class="vimtag"> <a name="v_g]">v_g]</a> </b>
<code class="special">{Visual}</code>g]              和 "g]" 相同，但使用高亮文本作为标识符。

                                                        <b class="vimtag"> <a name=":tj">:tj</a> </b> <b class="vimtag"> <a name=":tjump">:tjump</a> </b>
:tj[ump][!] <code class="special">[name]</code>      类似于 ":tselect"，但如果只有一个匹配，直接跳转之。

                                                        <b class="vimtag"> <a name=":stj">:stj</a> </b> <b class="vimtag"> <a name=":stjump">:stjump</a> </b>
:stj[ump][!] <code class="special">[name]</code>     ":tjump[!] <code class="special">[name]</code>" 并分割窗口以显示选择的标签。

                                                        <b class="vimtag"> <a name="g_CTRL-]">g_CTRL-]</a> </b>
g <code class="keystroke">CTRL-]</code>                类似于 <code class="keystroke">CTRL-]</code>，但使用 ":tjump" 而不是 ":tag"。

                                                        <b class="vimtag"> <a name="v_g_CTRL-]">v_g_CTRL-]</a> </b>
<code class="special">{Visual}</code>g <code class="keystroke">CTRL-]</code>        和 "g <code class="keystroke">CTRL-]</code>" 相同，但使用高亮文本作为标识符。

                                                        <b class="vimtag"> <a name=":tn">:tn</a> </b> <b class="vimtag"> <a name=":tnext">:tnext</a> </b>
:<code class="special">[count]</code>tn[ext][!]      跳转到向下 <code class="special">[count]</code> 个匹配的标签 (缺省为 1)。[!] 见
                         <a href="tagsrch.html#tag-!">tag-!</a> 。

                                                        <b class="vimtag"> <a name=":tp">:tp</a> </b> <b class="vimtag"> <a name=":tprevious">:tprevious</a> </b>
:<code class="special">[count]</code>tp[revious][!]  跳转到向上 <code class="special">[count]</code> 个匹配的标签 (缺省为 1)。[!] 见
                         <a href="tagsrch.html#tag-!">tag-!</a> 。

                                                        <b class="vimtag"> <a name=":tN">:tN</a> </b> <b class="vimtag"> <a name=":tNext">:tNext</a> </b>
:<code class="special">[count]</code>tN[ext][!]      和 ":tprevious" 相同。

                                                        <b class="vimtag"> <a name=":tr">:tr</a> </b> <b class="vimtag"> <a name=":trewind">:trewind</a> </b>
:<code class="special">[count]</code>tr[ewind][!]    跳转到第一个匹配的标签。如果给出 <code class="special">[count]</code>，跳到第
                        <code class="special">[count]</code> 个匹配的标签。[!] 见  <a href="tagsrch.html#tag-!">tag-!</a> 。

                                                        <b class="vimtag"> <a name=":tf">:tf</a> </b> <b class="vimtag"> <a name=":tfirst">:tfirst</a> </b>
:<code class="special">[count]</code>tf[irst][!]     和 ":trewind" 相同。

                                                        <b class="vimtag"> <a name=":tl">:tl</a> </b> <b class="vimtag"> <a name=":tlast">:tlast</a> </b>
:tl[ast][!]             跳到最后匹配的标签。[!] 见  <a href="tagsrch.html#tag-!">tag-!</a> 。

                                                        <b class="vimtag"> <a name=":lt">:lt</a> </b> <b class="vimtag"> <a name=":ltag">:ltag</a> </b>
:lt[ag][!] <code class="special">[name]</code>       跳转到标签 <code class="special">[name]</code> 上并在当前窗口的新位置列表中加入匹
                        配的标签。
                        <code class="special">[name]</code> 可以是正则表达式，见  <a href="tagsrch.html#tag-regexp">tag-regexp</a> 。如果
                        <code class="special">[name]</code> 没有给出，使用标签栈上最后的标签名。查找标签行
                        的搜索模式会加上 "\V" 前缀，转义所有的特殊字符 (very
                        nomagic)。显示匹配标签的位置列表独立于标签栈。[!] 见
                         <a href="tagsrch.html#tag-!">tag-!</a> 。

如果没有其他消息，Vim 显示跳到的是哪个匹配的标签，还有匹配标签的总数: 
<code class="example">        tag 1 of 3 or more</code>
" or more" 用于说明 Vim 并没有尝试完所有的 tags 文件。多用几次 ":tnext" 或者用
":tlast" 也许会找到更多。

如果因为有其他的消息使得你没看到这个消息，或者你想知道现在在哪里，以下这个命令
会再次显示本消息 (并跳转到最近一次的相同的标签): 
<code class="example">        :0tn</code>

                                                        <b class="vimtag"> <a name="tag-skip-file">tag-skip-file</a> </b>
如果找到一个匹配的标签，但是相应的文件却不存在，该匹配被跳过，而使用下一个匹
配。Vim 报告这一点，提醒你文件的丢失。在匹配列表的结束处，会给出错误。

                                                        <b class="vimtag"> <a name="tag-preview">tag-preview</a> </b>
标签匹配表也可用在预览窗口。命令和上面一样，除了前面有个 "p"。
<code class="notvi">{仅当编译时加入  <a href="various.html#+quickfix">+quickfix</a>  特性才有效}</code>

                                                        <b class="vimtag"> <a name=":pts">:pts</a> </b> <b class="vimtag"> <a name=":ptselect">:ptselect</a> </b>
:pts[elect][!] <code class="special">[name]</code>   ":tselect[!] <code class="special">[name]</code>" 并在预览窗口显示新的标签。详情见
                         <a href="windows.html#:ptag">:ptag</a> 。

                                                        <b class="vimtag"> <a name=":ptj">:ptj</a> </b> <b class="vimtag"> <a name=":ptjump">:ptjump</a> </b>
:ptj[ump][!] <code class="special">[name]</code>     ":tjump[!] <code class="special">[name]</code>" 并在预览窗口显示新的标签。详情见
                         <a href="windows.html#:ptag">:ptag</a> 。

                                                        <b class="vimtag"> <a name=":ptn">:ptn</a> </b> <b class="vimtag"> <a name=":ptnext">:ptnext</a> </b>
:<code class="special">[count]</code>ptn[ext][!]     在预览窗口里 ":tnext"。见  <a href="windows.html#:ptag">:ptag</a> 。

                                                        <b class="vimtag"> <a name=":ptp">:ptp</a> </b> <b class="vimtag"> <a name=":ptprevious">:ptprevious</a> </b>
:<code class="special">[count]</code>ptp[revious][!] 在预览窗口里 ":tprevious"。见  <a href="windows.html#:ptag">:ptag</a> 。

                                                        <b class="vimtag"> <a name=":ptN">:ptN</a> </b> <b class="vimtag"> <a name=":ptNext">:ptNext</a> </b>
:<code class="special">[count]</code>ptN[ext][!]     同 ":ptprevious"。

                                                        <b class="vimtag"> <a name=":ptr">:ptr</a> </b> <b class="vimtag"> <a name=":ptrewind">:ptrewind</a> </b>
:<code class="special">[count]</code>ptr[ewind][!]   在预览窗口中 ":trewind"。见  <a href="windows.html#:ptag">:ptag</a> 。

                                                        <b class="vimtag"> <a name=":ptf">:ptf</a> </b> <b class="vimtag"> <a name=":ptfirst">:ptfirst</a> </b>
:<code class="special">[count]</code>ptf[irst][!]    同 ":ptrewind"。

                                                        <b class="vimtag"> <a name=":ptl">:ptl</a> </b> <b class="vimtag"> <a name=":ptlast">:ptlast</a> </b>
:ptl[ast][!]            在预览窗口中见 ":tlast"。见  <a href="windows.html#:ptag">:ptag</a> 。

</section><hr class="doubleline" /><section class=inner>
<h4>4. 标签细节                                             <b class="vimtag"> <a name="tag-details">tag-details</a> </b></h4>
                                                        <b class="vimtag"> <a name="static-tag">static-tag</a> </b>
静态标签是为特定文件定义的标签。在 C 程序里，这可能是一个静态函数。

Vi 里跳转某个标签的同时设置当前搜索模式。这意味着在标签跳转后，"n" 命令不再查
找跳转前最后使用的模式了。Vim 没有这么做，因为我们认为这是一个错误。如果你真的
想要从前 Vi 那样的行为，在 <a href="options.html#'cpoptions'">'cpoptions'</a> 里设置 't' 标志位。

                                                        <b class="vimtag"> <a name="tag-binary-search">tag-binary-search</a> </b>
Vim 使用二分法查找标签文件，以快速查找到希望找到的标签 (如果编译时打开
 <a href="various.html#+tag_binary">+tag_binary</a>  特性的话)。不过这只有在 tags 文件按 ASCII 字节值排序才有效。因
此，如果没有匹配，Vim 会按照线性查找再来一次。如果你只想要线性查找。复位
<a href="options.html#'tagbsearch'">'tagbsearch'</a> 选项。或者更好的: 对 tags 文件排序！

<code class="note">注意</code> 如果不查找特定名字，标签的查找不使用二分法查找。这包括忽略大小写的查找或
不以固定字符串开始的正则表达式的查找。这样的标签搜索可能会慢很多。前者可以用大
小写合并排序来解决。详情见 <a href="options.html#'tagbsearch'">'tagbsearch'</a>。

                                                        <b class="vimtag"> <a name="tag-regexp">tag-regexp</a> </b>
":tag" 和 ":tselect" 命令接受正则表达式参数。 <a href="pattern.html#pattern">pattern</a>  可以看到如何使用特别的
字符。如果参数以 '/' 开始，它被认为是一个模式。如果不是，它被认为是按本义出现
的完整的标签名。
示例: 
<code class="example">    :tag main</code>
        跳转到最高优先级的 "main" 标签。 
<code class="example">    :tag /^get</code>
        跳转到最后优先级的 "get" 开始的标签。 
<code class="example">    :tag /norm</code>
        列出所有包含 "norm" 的标签，例如 "id_norm"。
如果参数既能按本义匹配，也能按正则表达式匹配，本义匹配有更高的优先级。比如，
":tag /open" 在 "open_file" 和 "file_open" 之前匹配 "open"。
如果使用模式，那么忽略大小写。如果你想在模式中匹配大小写，使用 "\C"。

                                                        <b class="vimtag"> <a name="tag-!">tag-!</a> </b>
如果标签在当前文件里，没有问题。不然，采取的行动取决于当前文件是否有改变，还有
命令之后是否加了 !，以及 <a href="options.html#'autowrite'">'autowrite'</a> 选项:

<code class="section">标签是否在      文件是          autowrite                       </code>
<code class="section">当前文件里      否改变  !       选项    行动    </code>
</section><hr class="singleline" /><section class=inner>
    是          x       x       x       转到标签
    否          否      x       x       读入其他文件，转到标签
    否          是      是      x       放弃当前文件，读入其他文件，转到标签
    否          是      否      开      写入当前文件，读入其他文件，转到标签
    否          是      否      关      失败
</section><hr class="singleline" /><section class=inner>

- 如果标签在当前文件里，该命令总能工作。
- 如果标签在另外的文件里而当前文件没有改变。那个文件成为当前文件，并读入到缓冲
  区里。
- 如果标签在另外的文件里而当前文件发生了改变。而命令后加了 !，那么当前文件的改
  变被放弃，那个文件成为当前文件，并读入缓冲区。
- 如果标签在另外的文件里而当前文件发生了改变。而 <a href="options.html#'autowrite'">'autowrite'</a> 选项被打开，那么
  当前文件的改变被保存，那个文件成为当前文件，并读入缓冲区。
- 如果标签在另外的文件里而当前文件发生了改变。而 <a href="options.html#'autowrite'">'autowrite'</a> 选项被关闭，那么
  该命令失败。此时，如果你想保存改变，先用 ":w" 命令，再用不带参数的 ":tag"。
  这是因为标签已经在堆栈上了。如果你想放弃改变，你可以用 ":tag!" 命令。

                                                        <b class="vimtag"> <a name="tag-security">tag-security</a> </b>
<code class="note">注意</code> Vim 为了安全原因禁止某些命令。这类似于在当前目录下的 exrc/vimrc 文件里使
用了 <a href="options.html#'secure'">'secure'</a> 选项。见  <a href="starting.html#trojan-horse">trojan-horse</a>  和  <a href="eval.html#sandbox">sandbox</a> 。
如果 <code class="special">{tagaddress}</code> 改变了缓冲区，你会得到<code class="note">警告</code>:
        "WARNING: tag command changed a buffer!!!"
在将来的版本里，也许会禁止对缓冲区的改变。这些都是为了安全原因: 有的人可能在
tags 文件里隐藏了恶意的命令。如果不这么做，你也许不能看到这一点。例如: 
<code class="example">        :$d|/tag-function-name/</code>
<code class="example"></code>
Vi 里跳转某个标签的同时设置当前搜索模式。Vim 没有这么做，以前的搜索模式还是记
住的。除非 <a href="options.html#'cpoptions'">'cpoptions'</a> 里设置了 't' 标志位。

                                        <b class="vimtag"> <a name="emacs-tags">emacs-tags</a> </b> <b class="vimtag"> <a name="emacs_tags">emacs_tags</a> </b> <b class="vimtag"> <a name="E430">E430</a> </b>
Emacs 风格的 tag 文件只有在 Vim 编译的时候加入  <a href="various.html#+emacs_tags">+emacs_tags</a>  特性时才有效。对
不起，这里没有 Emacs 标签文件的解释，支持它只是为了后向兼容。:-)。

Emacs 标签文件的行可能很长。Vim 只处理不超过 510 字节的行。要看到哪些行被忽
略，设置 <a href="options.html#'verbose'">'verbose'</a> 为 5 或更高。非 Emacs 的标签文件行接受任何长度。

                                                        <b class="vimtag"> <a name="tags-option">tags-option</a> </b>
<a href="options.html#'tags'">'tags'</a> 选项是文件名的列表。其中的每个文件都用来搜索标签。这可以用来指定不同于
缺省的 "tags" 文件的标签文件。它也可以用来访问一个公用的标签文件。

下列情况下，不再查找列表中的下个文件:
- 找到了当前缓冲区的匹配的静态标签。
- 找到了全局标签。
同时也取决于是否忽略大小写。以下条件下忽略大小写:
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "followic" 并且置位 <a href="options.html#'ignorecase'">'ignorecase'</a>
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "ignore"
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "smart" 且模式只包含小写字符。
- <a href="options.html#'tagcase'">'tagcase'</a> 为 "followscs" 且置位 <a href="options.html#'smartcase'">'smartcase'</a> 且模式只包含小写字符。
如果不忽略大小写，而当前标签文件找到大小写不符合的匹配，那么就会查找下一个文
件。如果没有匹配大小写的标签，则使用第一个大小写不符合的匹配。如果忽略大小写，
而找到全局的匹配 (不论大小写)，则立即使用之，而无须继续查找下一个文件。

如果标签文件以 "./" 开始，则 '.' 会被替代成当前的文件所在的路径。这样，你可以
使用当前文件所在的目录下的标签文件 (无论当前目录在哪里)。使用 "./" 的逻辑是，
你可以定义哪个标签文件最先查找: 先当前目录 ("tags,./tags")，还是先当前文件所处
的目录 ("./tags,tags")。

例如: 
<code class="example">        :set tags=./tags,tags,/home/user/commontags</code>
<code class="example"></code>
在这个例子里，先查找当前文件所处目录的 "tags" 文件。再查找当前目录下的 "tags"
文件。如果没有，再查找 "/home/user/commontags"。

要 Vi 兼容，可以在 <a href="options.html#'cpoptions'">'cpoptions'</a> 里包含 'd' 标志位。这样，"./tags" 会是当前目录
下的 tags 文件，而不是当前文件所在的目录下的。

除了逗号以外，也可以用空格。而在字符串值的选项里，空格需要用反斜杠转义: 
<code class="example">        :set tags=tags\ /home/user/commontags</code>
<code class="example"></code>
这样，要在文件名里包含空格，需要三个反斜杠。要在文件名里包含逗号，需要两个反斜
杠。例如，可以用: 
<code class="example">        :set tags=tag\\\ file,/home/user/common\\,tags</code>
<code class="example"></code>
来指定文件 "tag file" 和 "/home/user/common,tags"。<a href="options.html#'tags'">'tags'</a> 选项会包含值
"tag\ file,/home/user/common\,tags"。

如果打开 <a href="options.html#'tagrelative'">'tagrelative'</a> 选项 (这是缺省值) 而使用别的目录的标签文件，该标签文件
所引用的文件名相对于标签文件本身所处的目录。

</section><hr class="doubleline" /><section class=inner>
<h4>5. 标签文件格式                                 <b class="vimtag"> <a name="tags-file-format">tags-file-format</a> </b> <b class="vimtag"> <a name="E431">E431</a> </b></h4>
                                                <b class="vimtag"> <a name="ctags">ctags</a> </b> <b class="vimtag"> <a name="jtags">jtags</a> </b>
标签文件是外部程序创建的，比如 "ctags"。对每个函数，它会包含一个标签。有些版本
的 "ctags" 会为每个 "#define" 宏、类型等价定义 (typedef)、枚举 (enum) 等也创建
标签。

能产生标签文件的程序有:
ctags                   大多数 Unix 系统都能找到。只支持 C。只有基本的功能。
universal ctags         基于 exuberant ctags 的 ctags 维护版本。参见
                        <a href="https://ctags.io">https://ctags.io</a>。
                                                        <b class="vimtag"> <a name="Exuberant_ctags">Exuberant_ctags</a> </b>
exuberant ctags         这是很好的一个。它支持 C、C++、Java、Fortran、Eiffel
                        等等。它能为很多项目产生标签。见
                        <a href="http://ctags.sourceforge.net">http://ctags.sourceforge.net</a>。
                        2009 年后没有新版本。
etags                   和 Emacs 有关。支持很多语言。
JTags                   用 Java 编写，为 Java 而设计。可以在这里找到:
                        <a href="http://www.fleiner.com/jtags/">http://www.fleiner.com/jtags/</a>。
ptags.py                用 Python 编写，为 Python 而设计。它位于你的 Python 源
                        代码目录 Tools/scripts/ptags.py。
ptags                   用 Perl 编写，为 Perl 而设计。可以在这里找到:
                        <a href="http://www.eleves.ens.fr:8080/home/nthiery/Tags/">http://www.eleves.ens.fr:8080/home/nthiery/Tags/</a>。
gnatxref                为 Ada 而设计。见 <a href="http://www.gnuada.org/。gnatxref">http://www.gnuada.org/。gnatxref</a> 是
                        gnat 包的一部分。


标签文件的行应是以下两种格式之一:

1.  <code class="special">{tagname}</code>           <code class="special">{TAB}</code> <code class="special">{tagfile}</code> <code class="special">{TAB}</code> <code class="special">{tagaddress}</code>
2.  <code class="special">{tagname}</code>           <code class="special">{TAB}</code> <code class="special">{tagfile}</code> <code class="special">{TAB}</code> <code class="special">{tagaddress}</code> <code class="special">{term}</code> <code class="special">{field}</code> ..

之前支持一种旧格式。见  <a href="tagsrch.html#tag-old-static">tag-old-static</a> 。

第一种格式是普通的标签，和 Vi 完全兼容。传统的 ctags 实现只能产生这种格式。通
常，这用于被别的文件所引用的全局函数，

标签文件行可以用 <code class="special">&lt;NL&gt;</code> 或者 <code class="special">&lt;CR&gt;</code><code class="special">&lt;NL&gt;</code> 结尾。在 Macintosh 上，<code class="special">&lt;CR&gt;</code> 也能工作。<code class="special">&lt;CR&gt;</code>
和 <code class="special">&lt;NL&gt;</code> 字符不应该在行内出现。

第二个格式是新出现的。它在每行尾部的可选字段上包含了附加的信息。它和 Vi 后向兼
容。只有新的 ctags 版本 (比如 Universal ctags 或 Exuberant ctags) 才支持这种格
式。

<code class="special">{tagname}</code>       标识符。通常是函数的名字，但可以是任何标识符。不能包含 <code class="special">&lt;Tab&gt;</code>。
<code class="special">{TAB}</code>           单个 <code class="special">&lt;Tab&gt;</code> 字符。<code class="note">注意</code>: 以前的版本允许任意多个空白字符。现在不
                支持，因为 <code class="special">{tagfile}</code> 里可能包含空格。
<code class="special">{tagfile}</code>       包含 <code class="special">{tagname}</code> 定义的文件。可以是绝对路径或者相对路径。还可以
                包含环境变量甚至通配符 (尽管使用通配符很值得怀疑)。它不能包含
                <code class="special">&lt;Tab&gt;</code>。
<code class="special">{tagaddress}</code>    可以定位到 tag 的光标位置的 Ex 命令。可以是任何 Ex 命令，尽管
                有一些限制 (见  <a href="tagsrch.html#tag-security">tag-security</a> )。Posix 只允许行号和搜索命令，这
                也是最常用的。
<code class="special">{term}</code>          ;" 分号和双引号两个字符。这被 Vi 解释为注释的开始，从而忽略其
                后的部分。这样，就能和 Vi 后向兼容，因为 Vi 忽略后面的字段。例
                如:
                        APP     file    /^static int APP;$/;"   v
                如果 <code class="special">{tagaddress}</code> 不是行号或搜索模式，<code class="special">{term}</code> 必须是 |;"。这里
                的竖线结束命令 (不包含竖线)，而 ;" 使 Vi 忽略行的其它部分。例
                如:
                        APP     file.c  call cursor(3, 4)|;"    v

<code class="special">{field}</code> ..      可选的字段列表。每个字段有以下形式:

                        <code class="special">&lt;Tab&gt;</code><code class="special">{fieldname}</code>:<code class="special">{value}</code>

                <code class="special">{fieldname}</code> 标识字段，并且只能包含字母 [a-zA-Z]。
                <code class="special">{value}</code> 可以使任何字符串，但不能包含 <code class="special">&lt;Tab&gt;</code>。
                以下字符有特殊含义:
                        "\t" 代表 <code class="special">&lt;Tab&gt;</code>
                        "\r" 代表 <code class="special">&lt;CR&gt;</code>
                        "\n" 代表 <code class="special">&lt;NL&gt;</code>
                        "\\" 代表单个 '\' 字符

                有一个字段不需要 ':'。那就是标签的类型。它的处理方式就像前面
                有 "kind:" 开头那样。ctags 能产生的类型见它的文档。

                唯一的 Vim 能识别的其他字段是 "file:" (带一个空值)。用于静态变
                量。

标签文件的开头可以包含这样开始的行:
        !_TAG_
排序以后，他们一般都排在最前面。只有很少的以 "!" 开头的标签能排在他们前面。Vim
识别两项。第一个是指示文件是否排序的标志。如果找到这么一行，Vim 使用二分法查找
标签文件:
<code class="section">        !_TAG_FILE_SORTED<code class="special">&lt;Tab&gt;</code>1<code class="special">&lt;Tab&gt;</code><code class="special">{anything}</code> </code>

标签文件可以按大小写合并排序，以免忽略大小写时只能进行线性查找 (<a href="options.html#'ignorecase'">'ignorecase'</a>
置位且 <a href="options.html#'tagcase'">'tagcase'</a> 为 "followic" 或 <a href="options.html#'tagcase'">'tagcase'</a> 为 "ignore" 时忽略大小写)。详情见
<a href="options.html#'tagbsearch'">'tagbsearch'</a>。这时可以用值 2:
<code class="section">        !_TAG_FILE_SORTED<code class="special">&lt;Tab&gt;</code>2<code class="special">&lt;Tab&gt;</code><code class="special">{anything}</code> </code>

另一个 Vim 识别的标签指定标签文件的编码:
<code class="section">        !_TAG_FILE_ENCODING<code class="special">&lt;Tab&gt;</code>utf-8<code class="special">&lt;Tab&gt;</code><code class="special">{anything}</code> </code>
这里 "utf-8" 是标签们所用的编码。Vim 会把查找的标签从 <a href="options.html#'encoding'">'encoding'</a> 转为标签文件
的编码。当列出标签时，则反之。如果转换失败，则直接使用未经转换的标签。

                                                        <b class="vimtag"> <a name="tag-search">tag-search</a> </b>
标签搜索命令可以是任何 Ex 命令，但通常就是普通的搜索命令。比如:
<code class="section">        tag1    file1   /^main(argc, argv)/ </code>
<code class="section">        tag2    file2   108 </code>

该命令执行时总假设不设定 <a href="options.html#'magic'">'magic'</a>。搜索模式里仅有的特别的字符是 "^" (行首) 和
"$" (<code class="special">&lt;EOL&gt;</code>)。见  <a href="pattern.html#pattern">pattern</a> 。<code class="note">注意</code>，你必须在搜索文本里的每个反斜杠前加上反斜杠。
这和 Vi 反向兼容。

                                                        <b class="vimtag"> <a name="E434">E434</a> </b> <b class="vimtag"> <a name="E435">E435</a> </b>
如果该命令是一个普通的搜索命令 (也就是，以 "/" 或 "?" 开头和结尾)，会进行一些
特殊处理:
- 搜索从文件第 1 行开始。
  如果用 "/"，搜索方向为正向，"?" 则为反向。
  <code class="note">注意</code> <a href="options.html#'wrapscan'">'wrapscan'</a> 没有影响，总是搜索整个文件。
- 如果搜索失败，忽略大小写再重新尝试一次。如果还不行，搜索:
        "^tagname[ \t]*("
  (实际的标签前面加上 '^' 而后面加上 "[ \t]*(")。应用函数名的时候，它会找到在
  第 0 列的函数名。这会有助于找到该函数，即使它的参数和生成 tags 文件时有差
  异。如果还不行，进行另外一个搜索:
        "^[#a-zA-Z_].*\&lt;tagname[ \t]*("
  这意味着: 以 '#' 或者一个标识符开始的一行，包含标签本身，后面紧跟空白和一个
  '('。这会找到宏名和前面有返回类型的函数名。

                                                        <b class="vimtag"> <a name="tag-old-static">tag-old-static</a> </b>
直到 2019 年 3 月 (8.1.1092 补丁) 为止，曾经支持过另一种过时的格式:
    <code class="special">{tagfile}</code>:<code class="special">{tagname}</code> <code class="special">{TAB}</code> <code class="special">{tagfile}</code> <code class="special">{TAB}</code> <code class="special">{tagaddress}</code>

这种格式只限于静态标签。现在已经废弃了，被第二种格式取而代之。只有 Elvis 1.x，
旧版的 Vim 还有很少的 ctags 版本支持。静态变量用于本地函数，只有文件 <code class="special">{tagfile}</code>
才引用。<code class="note">注意</code> 对静态变量而言，<code class="special">{tagfile}</code> 的两次出现必须完全一致。关于如何使用静
态变量，见下面的  <a href="tagsrch.html#tags-option">tags-option</a> 。

删除了此支持，因为你既然可以更新 Vim 版本，也应可以更新 ctags 以支持第二种格
式。

</section><hr class="doubleline" /><section class=inner>
<h4>6. 头文件搜索                           <b class="vimtag"> <a name="include-search">include-search</a> </b> <b class="vimtag"> <a name="definition-search">definition-search</a> </b></h4>                                                        <b class="vimtag"> <a name="E387">E387</a> </b> <b class="vimtag"> <a name="E388">E388</a> </b> <b class="vimtag"> <a name="E389">E389</a> </b>

这些命令递归地查找当前文件和所有遇到的头文件的一个字符串。这可以用来查找变量的
定义，函数或者宏。如果只想查找当前缓冲区，用  <a href="pattern.html#pattern-searches">pattern-searches</a>  列出来的命令。

这些命令只有在编译时加入  <a href="various.html#+find_in_path">+find_in_path</a>  特性才会有效。

如果一个文件的某行包含另一个文件，那么那个文件在当前缓冲区继续之前先进行搜索。
头文件里包含的头文件也会被搜索。当头文件找不到时，它被悄悄地忽略掉。用
 <a href="tagsrch.html#:checkpath">:checkpath</a>  命令检查哪些文件可能找不到。是不是因为你的 <a href="options.html#'path'">'path'</a> 选项没有设对。
<code class="note">注意</code>: 被搜索的是头文件本身，不是可能正在编辑它的缓冲区。只有当前的文件除外，它
使用缓冲区里的行。

字符串可能是任何的关键字或者定义的宏。对于关键字，任何匹配都会找到。对于定义的
宏，只有用匹配 <a href="options.html#'define'">'define'</a> 选项的行才会被找到。它的缺省值是 "^#\s*define"。这对 C
程序适用，对于其它语言你可能想改变之。C++ 的一个例子见 <a href="options.html#'define'">'define'</a>。该字符串不能
包含换行符，只能匹配一行之内的文本。

如果找到一个定义的宏的匹配，并且该行以反斜杠结尾的话。行的显示在下一行继续。

"[" 开头的命令从当前文件开始查找。"]" 开始的命令从当前光标位置开始。

<a href="options.html#'include'">'include'</a> 选项用于定义可以包含另一个文件的行。缺省是 "\^#\s*include"。它适用于
C 程序。<code class="note">注意</code>: Vim 并不试图识别 C 语法。如果 <a href="options.html#'include'">'include'</a> 选项在 #ifdef/#endif 之
间或者注释内的一行上匹配，它也会被搜索到。<a href="options.html#'isfname'">'isfname'</a> 选项用于识别匹配之后的文件
名。

<a href="options.html#'path'">'path'</a> 选项用于查找不含绝对路径的头文件所在的目录。

<a href="options.html#'comments'">'comments'</a> 选项用来显示或者跳转到一行的命令。如果定义的模式可能包含注释，这些
行用来跳过搜索，除非使用 [!]。一个特例: 如果一行匹配模式 "^# *define"，它不会
被认为是注释。

如果你想列出所有的匹配，然后选择一个并跳转之，你可以使用一个映射来做这件事。这
里是一个例子: 
<code class="example"></code>
<code class="example">  :map &lt;F4&gt; [I:let nr = input("Which one: ")&lt;Bar&gt;exe "normal " .. nr .. "[\t"&lt;CR&gt;</code>

                                                        <b class="vimtag"> <a name="[i">[i</a> </b>
[i                      显示第一个包含光标所在的关键字的行。搜索从文件开头开
                        始。看起来像注释的行被忽略 (见 <a href="options.html#'comments'">'comments'</a> 选项)。如果
                        给出一个计数，跳转到第 count 个匹配的行，注释行不忽
                        略。

                                                        <b class="vimtag"> <a name="]i">]i</a> </b>
]i                      类似于 "[i"，但是从当前光标位置开始。

                                                        <b class="vimtag"> <a name=":is">:is</a> </b> <b class="vimtag"> <a name=":isearch">:isearch</a> </b>
:<code class="special">[range]</code>is[earch][!] <code class="special">[count]</code> [/]pattern[/]
                        类似于 "[i" 和 "]i"，但在 <code class="special">[range]</code> 行范围搜索 (缺省: 整
                        个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。

                                                        <b class="vimtag"> <a name="[I">[I</a> </b>
[I                      显示包含光标下的关键字的所有的行。找到的每行都显示文件
                        名和行号。搜索从文件头开始。

                                                        <b class="vimtag"> <a name="]I">]I</a> </b>
]I                      类似于 "[I"，但是从当前光标位置开始。

                                                        <b class="vimtag"> <a name=":il">:il</a> </b> <b class="vimtag"> <a name=":ilist">:ilist</a> </b>
:<code class="special">[range]</code>il[ist][!] [/]pattern[/]
                        类似于 "[I" 和 "]I"，但在 <code class="special">[range]</code> 行范围搜索 (缺省:
                        整个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。

                                                        <b class="vimtag"> <a name="[_CTRL-I">[_CTRL-I</a> </b>
[ <code class="keystroke">CTRL-I</code>                跳转到第一个包含光标所在的关键字的行。搜索从文件开头开
                        始。看起来像注释的行被忽略 (见 <a href="options.html#'comments'">'comments'</a> 选项)。如果
                        给出一个计数，跳转到第 count 个匹配的行，注释行不忽
                        略。


                                                        <b class="vimtag"> <a name="]_CTRL-I">]_CTRL-I</a> </b>
] <code class="keystroke">CTRL-I</code>                类似于 "[ <code class="keystroke">CTRL-I</code>"，但是从当前光标位置开始。

                                                        <b class="vimtag"> <a name=":ij">:ij</a> </b> <b class="vimtag"> <a name=":ijump">:ijump</a> </b>
:<code class="special">[range]</code>ij[ump][!] <code class="special">[count]</code> [/]pattern[/]
                        类似于 "[ <code class="keystroke">CTRL-I</code>"  和 "] <code class="keystroke">CTRL-I</code>"，但在 <code class="special">[range]</code> 行范围
                        搜索 (缺省: 整个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。

<code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-I</code>                                   <b class="vimtag"> <a name="CTRL-W_CTRL-I">CTRL-W_CTRL-I</a> </b> <b class="vimtag"> <a name="CTRL-W_i">CTRL-W_i</a> </b>
<code class="keystroke">CTRL-W</code> i                打开一个新窗口，把光标放在第一个包含光标所在的关键字的
                        行。搜索从文件开头开始。看起来像注释的行被忽略 (见
                        <a href="options.html#'comments'">'comments'</a> 选项)。如果给出一个计数，跳转到第 count 个
                        匹配的行，注释行不忽略。


                                                        <b class="vimtag"> <a name=":isp">:isp</a> </b> <b class="vimtag"> <a name=":isplit">:isplit</a> </b>
:<code class="special">[range]</code>isp[lit][!] <code class="special">[count]</code> [/]pattern[/]
                        类似于 "<code class="keystroke">CTRL-W</code> i"  和 "<code class="keystroke">CTRL-W</code> i"，但在 <code class="special">[range]</code> 行范围
                        搜索 (缺省: 整个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。


                                                        <b class="vimtag"> <a name="[d">[d</a> </b>
[d                      显示第一个包含光标所在的关键字的宏定义。搜索从文件头
                        开始。如果给出一个计数，跳转到第 count 个匹配的行。


                                                        <b class="vimtag"> <a name="]d">]d</a> </b>
]d                      类似于 "[d"，但是从当前光标位置开始。

                                                        <b class="vimtag"> <a name=":ds">:ds</a> </b> <b class="vimtag"> <a name=":dsearch">:dsearch</a> </b>
:<code class="special">[range]</code>ds[earch][!] <code class="special">[count]</code> [/]string[/]
                        类似于 "[d"  和 "]d"，但在 <code class="special">[range]</code> 行范围搜索 (缺省:
                        整个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。

                                                        <b class="vimtag"> <a name="[D">[D</a> </b>
[D                      显示包含光标下的宏的所有的宏定义。找到的每行都显示文件
                        名和行号。搜索从文件头开始。

                                                        <b class="vimtag"> <a name="]D">]D</a> </b>
]D                      类似于 "[D"，但是从当前光标位置开始。

                                                        <b class="vimtag"> <a name=":dli">:dli</a> </b> <b class="vimtag"> <a name=":dlist">:dlist</a> </b>
:<code class="special">[range]</code>dli[st][!] [/]string[/]
                        类似于  <a href="tagsrch.html#[D">[D</a>  和  <a href="tagsrch.html#]D">]D</a> ，但在 <code class="special">[range]</code> 行范围搜索 (缺省: 整
                        个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。
                        <code class="note">注意</code>  <a href="change.html#:dl">:dl</a>  功能等同带 "l" 标志位的  <a href="change.html#:delete">:delete</a> ，而不是
                         <a href="tagsrch.html#:dlist">:dlist</a> 。


                                                        <b class="vimtag"> <a name="[_CTRL-D">[_CTRL-D</a> </b>
[ <code class="keystroke">CTRL-D</code>                跳转到第一个包含光标所在的关键字的宏定义。搜索从文件头
                        开始。如果给出一个计数，跳转到第 count 个匹配的行。

                                                        <b class="vimtag"> <a name="]_CTRL-D">]_CTRL-D</a> </b>
] <code class="keystroke">CTRL-D</code>                类似于 "[ <code class="keystroke">CTRL-D</code>"，但是从当前光标开始。

                                                        <b class="vimtag"> <a name=":dj">:dj</a> </b> <b class="vimtag"> <a name=":djump">:djump</a> </b>
:<code class="special">[range]</code>dj[ump][!] <code class="special">[count]</code> [/]string[/]
                        类似于 "[ <code class="keystroke">CTRL-D</code>"  和 "] <code class="keystroke">CTRL-D</code>"，但是在 <code class="special">[range]</code> 行范
                        围内搜索 (缺省: 整个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 。


<code class="keystroke">CTRL-W</code> <code class="keystroke">CTRL-D</code>                                   <b class="vimtag"> <a name="CTRL-W_CTRL-D">CTRL-W_CTRL-D</a> </b> <b class="vimtag"> <a name="CTRL-W_d">CTRL-W_d</a> </b>
<code class="keystroke">CTRL-W</code> d                打开一个新窗口，把光标放在第一个包含光标所在的关键字的
                        宏定义行。搜索从文件头开始。如果给出一个计数，跳转到第
                        count 个匹配的行。

                                                        <b class="vimtag"> <a name=":dsp">:dsp</a> </b> <b class="vimtag"> <a name=":dsplit">:dsplit</a> </b>
:<code class="special">[range]</code>dsp[lit][!] <code class="special">[count]</code> [/]string[/]
                        类似于 "<code class="keystroke">CTRL-W</code> d"，但是在 <code class="special">[range]</code> 行范围内查找
                        (缺省: 整个文件)。
                        关于 [/] 和 [!] 见  <a href="tagsrch.html#:search-args">:search-args</a> 

                                        <b class="vimtag"> <a name=":che">:che</a> </b> <b class="vimtag"> <a name=":chec">:chec</a> </b> <b class="vimtag"> <a name=":check">:check</a> </b> <b class="vimtag"> <a name=":checkpath">:checkpath</a> </b>
:che[ckpath]            列出所有找不到的头文件。

:che[ckpath]!           列出所有的头文件。

                                                                <b class="vimtag"> <a name=":search-args">:search-args</a> </b>
以上命令通用的参数:
[!]     如果包含，查找包括识别为注释的匹配。如果不包含，则被识别为注释 (根据
        <a href="options.html#'comments'">'comments'</a> ) 或者是一个 C 注释 ("//" 之后或者 /* */ 之间) 的行不参加匹
        配。<code class="note">注意</code> 如果一行被识别为注释，但是注释在行中间结束，匹配可能丢失。另
        外，如果一行是注释，但是没有被识别 (根据 <a href="options.html#'comments'">'comments'</a>)，还是可能从中找到
        匹配。例子: 
<code class="example">                /* comment</code>
<code class="example">                   foobar */</code>
        还是可以找到 "foobar" 的匹配，因为该行没有被识别为注释 (即使语法高亮能
        够识别)。
        <code class="note">注意</code>: 因为宏定义一般看起来不像注释，[!] 对 ":dlist"、":dsearch" 和
        ":djump" 没有影响。
[/]     模式可以被 '/' 包围。没有 '/' 的话，只有完整单词的匹配，就像使用模式
        "\&lt;pattern\&gt;" 那样。只有在第二个 '/' 之后，下一个命令才可以通过 '|' 附
        加在后。例如: 
<code class="example">        :isearch /string/ | echo "the last one"</code>
        对于 ":djump"、":dsplit"、":dlist" 和 ":dsearch" 命令，模式是按本义理
        解的字符串，而不是搜索模式。

</section><hr class="doubleline" /><section class=inner>
<h4>7. 使用 <a href="options.html#'tagfunc'">'tagfunc'</a>                                               <b class="vimtag"> <a name="tag-function">tag-function</a> </b></h4>
可以给 Vim 提供函数，生成  <a href="tagsrch.html#:tag">:tag</a> 、 <a href="tagsrch.html#:tselect">:tselect</a>  等命令和  <a href="tagsrch.html#CTRL-]">CTRL-]</a>  这样的普通模式
标签命令所使用的标签列表。

生成标签列表的函数通过设置 <a href="options.html#'tagfunc'">'tagfunc'</a> 选项指定。此函数调用时带三个参数:
   pattern      标签搜索时使用的标签标识符或模式。
   flags        包含控制函数行为的标志位字符串。
   info         包含以下项目的字典:
                    buf_ffname    可用于优先级的完整文件名。
                    user_data     如有，之前通过 tagfunc 存在标签栈里的定制数
                                  据字符串。

<code class="note">注意</code> 老式函数里，使用参数名前要加上 "a:" 前缀。

目前可以给标签函数传递多至三个的标志位:
  'c'           函数是处理中的普通命令调用的
                (助记: 标签函数可用光标附近的上下文 (context) 来更好地生成标签
                列表。)
  'i'           插入模式中，用户在补全标签 (用  <a href="insert.html#i_CTRL-X_CTRL-]">i_CTRL-X_CTRL-]</a>  或
                <a href="options.html#'completeopt'">'completeopt'</a> 包含  <a href="motion.html#t">t</a>  时)。
  'r'           tagfunc 的首个参数应被解释为  <a href="pattern.html#pattern">pattern</a>  (见  <a href="tagsrch.html#tag-regexp">tag-regexp</a> )，就像
                这样: 
<code class="example">                  :tag /pat</code>
                插入模式下的补全也会如此。
                如果不给出此标志位，参数通常按本义理解为完整标签名。

<code class="note">注意</code> 设置 <a href="options.html#'tagfunc'">'tagfunc'</a> 时， <a href="tagsrch.html#tag-priority">tag-priority</a>  描述的标签优先级不适用。相反，优先级完
全由函数返回的列表元素的顺序来决定。
                                                                <b class="vimtag"> <a name="E987">E987</a> </b>
函数应返回字典项目的列表。每个字典至少包含以下项，所有值都是字符串:
        name            标签名。
        filename        标签定义所在的文件名。可以是相对于当前目录的相对路径，
                        也可以是完整路径。
        cmd             用于在文件中定位标签的 Ex 命令。可以是 Ex 搜索模式或是
                        行号。
<code class="note">注意</code> 格式和  <a href="builtin.html#taglist()">taglist()</a>  类似，这样可以使用后者的输出来生成结果。
下列域是可选的:
        kind            标签的类型。
        user_data       存于标签栈中的定制数据，可用于区别不同操作间的标签。

如果函数返回  <a href="eval.html#v:null">v:null</a>  而不是列表，执行标准的标签查找。

在 <a href="options.html#'tagfunc'">'tagfunc'</a> 内不允许改动标签栈。 <b class="vimtag"> <a name="E986">E986</a> </b>
在 <a href="options.html#'tagfunc'">'tagfunc'</a> 内不允许关闭窗口或改变窗口。 <b class="vimtag"> <a name="E1299">E1299</a> </b>

下面是一个用于 <a href="options.html#'tagfunc'">'tagfunc'</a> 函数的假想例。它使用  <a href="builtin.html#taglist()">taglist()</a>  的输出来生成结果: 按
文件名的逆序生成标签列表。

<code class="example">        function TagFunc(pattern, flags, info)</code>
<code class="example">          function CompareFilenames(item1, item2)</code>
<code class="example">            let f1 = a:item1['filename']</code>
<code class="example">            let f2 = a:item2['filename']</code>
<code class="example">            return f1 &gt;=# f2 ?</code>
<code class="example">                        \ -1 : f1 &lt;=# f2 ? 1 : 0</code>
<code class="example">          endfunction</code>
<code class="example"></code>
<code class="example">          let result = taglist(a:pattern)</code>
<code class="example">          call sort(result, "CompareFilenames")</code>
<code class="example"></code>
<code class="example">          return result</code>
<code class="example">        endfunc</code>
<code class="example">        set tagfunc=TagFunc</code>


 vim:tw=78:ts=8:noet:ft=help:norl:
</section>
</article>
<footer>
Generated by vim2html
</footer>
</body>
</html>
